home *** CD-ROM | disk | FTP | other *** search
- // VirtualDub - Video processing and capture application
- // System library component
- // Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
- //
- // Beginning with 1.6.0, the VirtualDub system library is licensed
- // differently than the remainder of VirtualDub. This particular file is
- // thus licensed as follows (the "zlib" license):
- //
- // This software is provided 'as-is', without any express or implied
- // warranty. In no event will the authors be held liable for any
- // damages arising from the use of this software.
- //
- // Permission is granted to anyone to use this software for any purpose,
- // including commercial applications, and to alter it and redistribute it
- // freely, subject to the following restrictions:
- //
- // 1. The origin of this software must not be misrepresented; you must
- // not claim that you wrote the original software. If you use this
- // software in a product, an acknowledgment in the product
- // documentation would be appreciated but is not required.
- // 2. Altered source versions must be plainly marked as such, and must
- // not be misrepresented as being the original software.
- // 3. This notice may not be removed or altered from any source
- // distribution.
-
- #include "stdafx.h"
- #include <math.h>
- #include <vd2/system/math.h>
- #include <vd2/system/int128.h>
-
- int VDRoundToInt(double x) {
- return (int)floor(x + 0.5);
- }
-
- long VDRoundToLong(double x) {
- return (long)floor(x + 0.5);
- }
-
- sint32 VDRoundToInt32(double x) {
- return (sint32)floor(x + 0.5);
- }
-
- sint64 VDRoundToInt64(double x) {
- return (sint64)floor(x + 0.5);
- }
-
- #ifdef _M_IX86
- sint64 __declspec(naked) __stdcall VDFractionScale64(uint64 a, uint32 b, uint32 c, uint32& remainder) {
- __asm {
- push edi
- push ebx
- mov edi, [esp+12+8] ;edi = b
- mov eax, [esp+4+8] ;eax = a[lo]
- mul edi ;edx:eax = a[lo]*b
- mov ecx, eax ;ecx = (a*b)[lo]
- mov eax, [esp+8+8] ;eax = a[hi]
- mov ebx, edx ;ebx = (a*b)[mid]
- mul edi ;edx:eax = a[hi]*b
- add eax, ebx
- mov ebx, [esp+16+8] ;ebx = c
- adc edx, 0
- div ebx ;eax = (a*b)/c [hi], edx = (a[hi]*b)%c
- mov edi, eax ;edi = (a[hi]*b)/c
- mov eax, ecx ;eax = (a*b)[lo]
- mov ecx, [esp+20+8]
- div ebx ;eax = (a*b)/c [lo], edx = (a*b)%c
- mov [ecx], edx
- mov edx, edi
- pop ebx
- pop edi
- ret 20
- }
- }
-
- uint64 __declspec(naked) __stdcall VDUMulDiv64x32(uint64 a, uint32 b, uint32 c) {
- __asm {
- mov eax, [esp+4] ;eax = a0
- mul dword ptr [esp+12] ;edx:eax = a0*b
- mov dword ptr [esp+4], eax ;tmp = a0*b[0:31]
- mov ecx, edx ;ecx = a0*b[32:63]
- mov eax, [esp+8] ;eax = a1
- mul dword ptr [esp+12] ;edx:eax = a1*b
- add eax, ecx ;edx:eax += a0*b[32:95]
- adc edx, 0 ;(cont.)
- cmp edx, [esp+16] ;test if a*b[64:95] >= c; equiv to a*b >= (c<<64)
- jae invalid ;abort if so (overflow)
- div dword ptr [esp+16] ;edx,eax = ((a*b)[32:95]/c, (a*b)[32:95]%c)
- mov ecx, eax
- mov eax, [esp+4]
- div dword ptr [esp+16]
- mov edx, ecx
- ret 16
- invalid:
- mov eax, -1 ;return FFFFFFFF'FFFFFFFF
- mov edx, -1
- ret 16
- }
- }
- #endif
-
- sint64 VDMulDiv64(sint64 a, sint64 b, sint64 c) {
- bool flip = false;
-
- if (a < 0) {
- a = -a;
- flip = true;
- }
-
- if (b < 0) {
- b = -b;
- flip = !flip;
- }
-
- if (c < 0) {
- c = -c;
- flip = !flip;
- }
-
- uint64 rem;
- uint64 v = VDUDiv128x64To64(VDUMul64x64To128((uint64)a, (uint64)b), (uint64)c, rem);
-
- if ((rem+rem) >= (uint64)c)
- ++v;
-
- return flip ? -(sint64)v : (sint64)v;
- }
-